home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 April / macformat-023.iso / Shareware in MacFormat / brailler0.5b / brlr ƒ / WindoidWDEF / WindoidWDEF.c next >
Encoding:
C/C++ Source or Header  |  1994-12-20  |  10.5 KB  |  366 lines  |  [TEXT/KAHL]

  1. /*    Window definition ('WDEF') to draw floating "windoid" windows. There are
  2.     several variation codes (see comments in header).
  3.     
  4.     931215 aih drag bar is erased if window is unhilited
  5.     931207 aih added zoom and grow boxes
  6.     931114 aih created */
  7.  
  8. #include "WindoidWDEF.h"
  9.  
  10. /* return absolute value of x */
  11. #define abs(x) ((x) < 0 ? -(x) : x)
  12.  
  13. /* rectangles for the various parts of a window */
  14. struct rects {
  15.     Rect border;    /* border around structure area */
  16.     Rect drag;        /* drag area */
  17.     Rect goaway;    /* go away area */
  18.     Rect zoom;        /* zoom area */
  19.     Rect grow;        /* grow area */
  20. };
  21.  
  22. /*----------------------------------------------------------------------------*/
  23. /* rectangle calculation */
  24. /*----------------------------------------------------------------------------*/
  25.  
  26. /* return structure rectangle */
  27. static void getstructure(WindowPeek win, Rect *structure)
  28. {
  29.     /* assert: win->visible == true */
  30.     *structure = (**win->strucRgn).rgnBBox;
  31. }
  32.  
  33. /* return content rectangle */
  34. static void getcontent(WindowPeek win, Rect *content)
  35. {
  36.     /* assert: win->visible == true */
  37.     *content = (**win->contRgn).rgnBBox;
  38. }
  39.  
  40. /* given a window's content rectangle, calculates its structure rectangle
  41.     (works even with invisible windows) */
  42. static void calcstructure(short var, WindowPeek win, Rect *content)
  43. {
  44.     InsetRect(content, -kWindoidBorderSize, -kWindoidBorderSize);
  45.     content->bottom += kWindoidShadowSize;
  46.     content->right += kWindoidShadowSize;
  47.     if (WindoidDragLeft(var))
  48.         content->left -= kWindoidDragSize + 1;
  49.     else if (WindoidDragTop(var))
  50.         content->top -= kWindoidDragSize + 1;
  51. }
  52.  
  53. /* given a window calculate its content rectangle (works even with
  54.     invisible windows) */
  55. static void calccontent(short var, WindowPeek win, Rect *content)
  56. {
  57.     GrafPtr port = (GrafPtr) win;
  58.     
  59.     *content = port->portRect;
  60.     OffsetRect(content, -port->portBits.bounds.left, -port->portBits.bounds.top);
  61. }
  62.  
  63. /* calculate the rectangles of the window (e.g., drag, grow, zoom, etc.),
  64.     given the structure and content rectangles */
  65. static void calcrects2(short var, WindowPeek win, struct rects *rects,
  66.     const Rect *structure, const Rect *content)
  67. {
  68.     rects->border = *structure;
  69.     rects->border.bottom -= kWindoidShadowSize;
  70.     rects->border.right -= kWindoidShadowSize;
  71.     rects->drag = rects->border;
  72.     InsetRect(&rects->drag, kWindoidBorderSize, kWindoidBorderSize);
  73.     if (WindoidDragLeft(var)) {
  74.         rects->drag.right = rects->drag.left + kWindoidDragSize;
  75.         rects->goaway.top = rects->drag.top + 8;
  76.         rects->goaway.left = rects->drag.left + 1;
  77.         rects->zoom.top = rects->drag.bottom - 7 - kWindoidZoomSize;
  78.         rects->zoom.left = rects->drag.left + 1;
  79.     }
  80.     else {
  81.         rects->drag.bottom = rects->drag.top + kWindoidDragSize;
  82.         rects->goaway.top = rects->drag.top + 1;
  83.         rects->goaway.left = rects->drag.left + 8;
  84.         rects->zoom.top = rects->drag.top + 1;
  85.         rects->zoom.left = rects->drag.right - 7 - kWindoidZoomSize;
  86.     }
  87.     rects->goaway.bottom = rects->goaway.top + kWindoidGoAwaySize;
  88.     rects->goaway.right = rects->goaway.left + kWindoidGoAwaySize;
  89.     rects->zoom.bottom = rects->zoom.top + kWindoidZoomSize;
  90.     rects->zoom.right = rects->zoom.left + kWindoidZoomSize;
  91.     rects->grow = *content;
  92.     rects->grow.top = rects->grow.bottom - kWindoidGrowSize;
  93.     rects->grow.left = rects->grow.right - kWindoidGrowSize;
  94.     OffsetRect(&rects->grow, 1, 1);
  95. }
  96.  
  97. /* calculate the rectangles of the window (e.g., drag, grow, zoom, etc.) */
  98. static void calcrects(short var, WindowPeek win, struct rects *rects)
  99. {
  100.     Rect structure, content;
  101.     
  102.     getstructure(win, &structure);
  103.     getcontent(win, &content);
  104.     calcrects2(var, win, rects, &structure, &content);
  105. }
  106.  
  107. /*----------------------------------------------------------------------------*/
  108. /* pattern manipulation */
  109. /*----------------------------------------------------------------------------*/
  110.  
  111. /* invert bits of pattern so it alligns nicely on the screen */
  112. static void patinvert(Pattern pat)
  113. {
  114.     pat[0] = ~pat[0];
  115.     pat[2] = ~pat[2];
  116.     pat[4] = ~pat[4];
  117.     pat[6] = ~pat[6];
  118. }
  119.  
  120. /* rotate bits of pattern so it alligns nicely on the screen */
  121. static void patrotate(Pattern pat)
  122. {
  123.     unsigned long *shift = (unsigned long *) pat;
  124.     shift[1] = shift[0] >>= 8;
  125. }
  126.  
  127. /*----------------------------------------------------------------------------*/
  128. /* zoom window utilities */
  129. /*----------------------------------------------------------------------------*/
  130.  
  131. /* Return true if the window is in the standard state
  132.     (i.e., is zoomed, see IM-IV, p10), otherwise it must
  133.     be in the user state so set the user state to the
  134.     window's content rectangle. */
  135. static Boolean zoomed(WindowPeek win)
  136. {
  137.     Rect content;
  138.     Rect stdState;
  139.     Boolean result = false;
  140.     
  141.     /* assert: win->spareFlag == true && win->dataHandle != NULL */
  142.     getcontent(win, &content);
  143.     stdState = (**(WStateData**)win->dataHandle).stdState;
  144.     result =
  145.         (abs(content.top - stdState.top) <= kWindoidZoomMargin &&
  146.          abs(content.left - stdState.left) <= kWindoidZoomMargin &&
  147.          abs(content.bottom - stdState.bottom) <= kWindoidZoomMargin &&
  148.          abs(content.right - stdState.right) <= kWindoidZoomMargin);
  149.     if (! result)
  150.         (**(WStateData**)win->dataHandle).userState = content;
  151.     return(result); 
  152. }
  153.  
  154. /*----------------------------------------------------------------------------*/
  155. /* window definition routines */
  156. /*----------------------------------------------------------------------------*/
  157.  
  158. /* draw window; param must be short, not long, see technote */
  159. static long draw(short var, WindowPeek win, short param)
  160. {
  161.     Pattern pat;
  162.     PenState pen;
  163.     struct rects rects;
  164.  
  165.     if (win->visible) {
  166.         calcrects(var, win, &rects);
  167.         GetPenState(&pen);
  168.         PenNormal();
  169.         switch (param) {
  170.         case wNoHit:
  171.             
  172.             /* draw border */
  173.             FrameRect(&rects.border);
  174.  
  175.             /* draw shadow */
  176.             MoveTo(rects.border.right, rects.border.top + 2);
  177.             LineTo(rects.border.right, rects.border.bottom);
  178.             LineTo(rects.border.left + 2, rects.border.bottom);
  179.  
  180.             /* draw drag region */
  181.             if (WindoidDrag(var)) {
  182.  
  183.                 /* draw drag pattern */
  184.                 if (win->hilited) {
  185.                     StuffHex(pat, (unsigned char *) "\pAA00AA00AA00AA00");
  186.                     if (rects.border.left & 1) patinvert(pat);
  187.                     if (rects.border.top & 1) patrotate(pat);
  188.                     FillRect(&rects.drag, pat);
  189.                 }
  190.                 else
  191.                     EraseRect(&rects.drag);
  192.                     
  193.                 /* draw line between drag and content regions */
  194.                 if (WindoidDragLeft(var))
  195.                     MoveTo(rects.drag.right, rects.drag.top);
  196.                 else if (WindoidDragTop(var))
  197.                     MoveTo(rects.drag.left, rects.drag.bottom);
  198.                 LineTo(rects.drag.right, rects.drag.bottom);
  199.  
  200.                 /* draw go away region */
  201.                 if (win->goAwayFlag) {
  202.                     InsetRect(&rects.goaway, -1, -1);
  203.                     EraseRect(&rects.goaway);
  204.                     InsetRect(&rects.goaway, 1, 1);
  205.                     FrameRect(&rects.goaway);
  206.                 }
  207.                 
  208.                 /* draw zoom region */
  209.                 if (WindoidZoom(var)) {
  210.                     InsetRect(&rects.zoom, -1, -1);
  211.                     EraseRect(&rects.zoom);
  212.                     InsetRect(&rects.zoom, 1, 1);
  213.                     FrameRect(&rects.zoom);
  214.                     rects.zoom.bottom -= kWindoidZoomSize / 2 - 1;
  215.                     rects.zoom.right -= kWindoidZoomSize / 2 - 1;
  216.                     FrameRect(&rects.zoom);
  217.                 }
  218.             }
  219.             break;
  220.         case wInGoAway:
  221.             InsetRect(&rects.goaway, 1, 1);
  222.             InvertRect(&rects.goaway);
  223.             break;
  224.         case wInZoomIn:
  225.         case wInZoomOut:
  226.             InsetRect(&rects.zoom, 1, 1);
  227.             InvertRect(&rects.zoom);
  228.             break;
  229.         }
  230.         SetPenState(&pen);
  231.     }
  232.     return(0);
  233. }
  234.  
  235. /* return area hit by mouse */
  236. static long hit(short var, WindowPeek win, long param)
  237. {
  238.     Rect structure, content;
  239.     Point where = *(Point *) ¶m;
  240.     long result = wNoHit;
  241.     struct rects rects;
  242.     
  243.     getstructure(win, &structure);
  244.     getcontent(win, &content);
  245.     if (PtInRect(where, &structure)) {
  246.         calcrects(var, win, &rects);
  247.         if (WindoidGrow(var) && PtInRect(where, &rects.grow))
  248.             result = wInGrow;
  249.         else if (PtInRect(where, &content))
  250.             result = wInContent;
  251.         else if (WindoidDrag(var)) {
  252.             if (win->goAwayFlag && PtInRect(where, &rects.goaway))
  253.                 result = wInGoAway;
  254.             else if (WindoidZoom(var) && PtInRect(where, &rects.zoom))
  255.                 result = zoomed(win) ? wInZoomIn : wInZoomOut;
  256.             else if (PtInRect(where, &rects.drag))
  257.                 result = wInDrag;
  258.         }
  259.     }
  260.     return(result);
  261. }
  262.  
  263. /* calculate the window's content and structure regions and
  264.     update zoom state */
  265. static long calc(short var, WindowPeek win, long param)
  266. {
  267.     Rect area;
  268.     
  269.     calccontent(var, win, &area);
  270.     RectRgn(win->contRgn, &area);
  271.     calcstructure(var, win, &area);
  272.       RectRgn(win->strucRgn, &area);
  273.       if (WindoidZoom(var))
  274.           (void) zoomed(win);
  275.     return(0);
  276. }
  277.  
  278. /* initialize the window */
  279. static long new(short var, WindowPeek win, long param)
  280. {
  281.     Rect content;
  282.     
  283.     if (WindoidZoom(var)) {
  284.         win->spareFlag = true;
  285.         win->dataHandle = NewHandleClear(sizeof(WStateData));
  286.         calccontent(var, win, &content);
  287.         (**(WStateData**)win->dataHandle).userState = content;
  288.         (**(WStateData**)win->dataHandle).stdState = content;
  289.     }
  290.      return(0);
  291. }
  292.  
  293. /* dispose of private store */
  294. static long dispose(short var, WindowPeek win, long param)
  295. {
  296.     if (WindoidZoom(var) && win->dataHandle)
  297.         DisposHandle(win->dataHandle);
  298.      return(0);
  299. }
  300.  
  301. /* draw lines for tracking the size box */
  302. static long grow(short var, WindowPeek win, long param)
  303. {
  304.     Rect content;
  305.     Rect structure;
  306.     struct rects rects;
  307.     
  308.     /* calculate rectangles based on
  309.         rectangle parameter */
  310.     structure = content = *(Rect *) param;
  311.     calcstructure(var, win, &structure);
  312.     calcrects2(var, win, &rects, &structure, &content);
  313.  
  314.     /* draw line around structure region */
  315.     FrameRect(&structure);
  316.     
  317.     /* draw line between drag and content regions */
  318.     if (WindoidDrag(var)) {
  319.         if (WindoidDragLeft(var))
  320.             MoveTo(rects.drag.right, rects.drag.top);
  321.         else if (WindoidDragTop(var))
  322.             MoveTo(rects.drag.left, rects.drag.bottom);
  323.         LineTo(rects.drag.right, rects.drag.bottom);
  324.     }
  325.         
  326.     /* draw lines around size box and scroll bar areas */
  327.     MoveTo(rects.grow.left, structure.bottom);
  328.     LineTo(rects.grow.left, WindoidDragTop(var) ? rects.drag.bottom :
  329.                                                                  structure.top);
  330.     MoveTo(structure.right, rects.grow.top);
  331.     LineTo(structure.left, rects.grow.top);
  332.      return(0);
  333. }
  334.  
  335. /* draw the grow icon */
  336. static long drawgrow(short var, WindowPeek win, long param)
  337. {
  338.     struct rects rects;
  339.     GrafPtr port;
  340.     
  341.     GetPort(&port);
  342.     SetPort((WindowPtr) win);
  343.     calcrects(var, win, &rects);
  344.     FrameRect(&rects.grow);
  345.     InsetRect(&rects.grow, 2, 2);
  346.     FrameRect(&rects.grow);
  347.     SetPort(port);
  348.      return(0);
  349. }
  350.  
  351. pascal long main(short var, WindowPtr window, short msg, long param)
  352. {
  353.     WindowPeek win = (WindowPeek) window;
  354.     
  355.     switch (msg) {
  356.     case wDraw:            return(draw(var, win, param));
  357.     case wHit:            return(hit(var, win, param));
  358.     case wCalcRgns:    return(calc(var, win, param));
  359.     case wNew:            return(new(var, win, param));
  360.     case wDispose:        return(dispose(var, win, param));
  361.     case wGrow:            return(grow(var, win, param));
  362.     case wDrawGIcon:    return(drawgrow(var, win, param));
  363.     }
  364.     return(0);
  365. }
  366.